package com.yuke.cloud.service.wmc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yuke.cloud.common.base.dto.MsgNotificationBody;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.common.util.RedisKeyUtil;
import com.yuke.cloud.service.api.cmc.dto.CmsSecKillSkuDto;
import com.yuke.cloud.service.api.cmc.service.CmcFeignApi;
import com.yuke.cloud.service.api.omc.service.OmcOrderFeignApi;
import com.yuke.cloud.service.api.opc.service.OpcSendNotifyFeignApi;
import com.yuke.cloud.service.api.pmc.service.PmcFeignApi;
import com.yuke.cloud.service.wmc.config.Printconfig;
import com.yuke.cloud.service.wmc.entity.*;
import com.yuke.cloud.service.wmc.printHttpUtil.HttpUtils;
import com.yuke.cloud.service.wmc.service.*;
import com.yuke.cloud.service.wmc.util.MD5;
import com.yuke.cloud.service.wmc.util.printUtil;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class WmsAsyncServiceImpl extends BaseService<WmsStorage> implements WmsAsyncService {
    @Resource
    private OmcOrderFeignApi omcOrderFeignApi;
    @Autowired
    private WmsWarehouseService wmsWarehouseService;
    @Autowired
    private WmsStorageRecordService wmsStorageRecordService;
    @Autowired
    private WmsWarehouseShopService wmsWarehouseShopService;
    @Resource
    private PmcFeignApi pmcFeignApi;
    @Resource
    private OpcSendNotifyFeignApi opcSendNotifyFeignApi;
    @Autowired
    private LmsExpressService lmsExpressService;
    @Resource
    private WmsStockOutService wmsStockOutService;
    @Resource
    private WmsStorageService wmsStorageService;
    @Resource
    private WmsStockInService wmsStockInService;
    @Resource
    private CmcFeignApi cmcFeignApi;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private WmsPrinterService wmsPrinterService;


    @Async
    @Override
    public String getResult1() {
        System.out.println("getResult() start..."+new Date());
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("getResult() end..."+new Date());
        return "TestAsync";
    }

    @Async
    @Override
    public String getResult2() {
        System.out.println("getResult2() start..."+new Date());
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("getResult2() end..."+new Date());
        return "TestAsync";
    }


    @Override
    public Integer printOrder (JSONObject jsonObject, Long warehouseId) {
        String notifyMsg = "";
        Byte shippingType = Byte.valueOf(jsonObject.get("shippingType").toString());
        Long expressId = null;
        //订单id和快递公司id
        String orderid = jsonObject.get("orderId").toString();
        String order_no = orderid;
        String waybill_no = orderid;  // 快递单号默认与订单号一样，对于自配送来说暂时没有快递单号
        String shopId = jsonObject.get("shopId").toString();
        Object goodsList = jsonObject.get("goodsList");
        JSONArray objects1 = JSON.parseArray(goodsList.toString());
        if (shippingType == 1 && !Boolean.valueOf(jsonObject.get("isFactory").toString())) {  // 物流，厂家直销商品的快递由厂家直接发货
            //收货人的地址
            Map region_county_id = wmsWarehouseService.getaddressbyregionid(Long.valueOf(jsonObject.get("regionCountyId").toString()));
            System.out.println("收货人地址" + "============================================================");
            System.out.println(region_county_id);
            //仓库的地址
            // todo 需要根据订单所属仓库进行修改，订单为非厂家直销且为物流的订单才进入物流逻辑 20190717
            Map address = null;
            if (warehouseId == null) {
                address = wmsWarehouseService.getwarehouseaddressbyshopid(shopId);
            } else {
                address = wmsWarehouseService.getWarehouseAddress(warehouseId);
            }
            System.out.println("仓库地址，发货人地址" + "============================================================");
            System.out.println(address);

            // add by wg 20190219 获取快递公司
            String loginName = null;
            String loginPassword = null;
            String expressName = null;
            String expressShortName = null;
            String siteFlag = "";
            if (PublicUtil.isNotEmpty(jsonObject.get("expressId"))) {
                expressId = Long.valueOf(jsonObject.get("expressId").toString());
                LmsExpress lmsExpressTemp = lmsExpressService.findById(expressId);

                if (PublicUtil.isNotEmpty(lmsExpressTemp)) {
                    loginName = lmsExpressTemp.getLoginName();
                    loginPassword = lmsExpressTemp.getLoginPassword();
                    expressName = lmsExpressTemp.getExpressName();
                    expressShortName = lmsExpressTemp.getExpressShortName();
                    siteFlag = lmsExpressTemp.getSiteFlag();
                }
            }

            if (expressId == null || loginName == null) {  // 如果快递公司没有，则获取默认的
                Example example = new Example(LmsExpress.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("warehouseId", warehouseId);
                example.setOrderByClause("is_default DESC");
                List<LmsExpress> select = lmsExpressService.selectByExample(example);

                if (select == null || select.size() == 0) {
                    return -1;
                }
                loginName = select.get(0).getLoginName();
                loginPassword = select.get(0).getLoginPassword();
                expressId = select.get(0).getExpressId();
                expressName = select.get(0).getExpressName();
                expressShortName = select.get(0).getExpressShortName();
                siteFlag = select.get(0).getSiteFlag();
            }

            //从数据库获取默认的快递公司名称，测试暂时用顺丰
            // 先给对应的快递公司下单，获取电子面单号，然后调用接口打印
            //        String transid = "sf"; // todo 写死成顺丰的，需要参考快宝平台文档中的ID及数据库指定的快递公司
            String transid = expressShortName;  //add by wg 20190219
            String host = "http://kop.kuaidihelp.com";
            String path = "/api";
            String method = "POST";
            Map<String, String> headers = new HashMap<String, String>();
            //根据API的要求，定义相对应的Content-Type
            headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            Map<String, String> querys = new HashMap<String, String>();
            Map<String, String> bodys = new HashMap<String, String>();
            bodys.put("app_id", Printconfig.userId);
            bodys.put("method", "account.waybill.get");
            String ts = System.currentTimeMillis() + "";
            bodys.put("ts", ts);
            String str = Printconfig.userId + "account.waybill.get" + ts + Printconfig.apikey;
            try{
                String sign = MD5.MD5(str, "utf-8");
                bodys.put("sign", sign);
            }catch (Exception e){
                System.out.println(e);
                return 0;
            }


            Map<String, Object> data = new HashMap<String, Object>();//对应data
            //发送者(必填部分)
            Map<String, Object> sender = new HashMap<String, Object>();
            sender.put("city", address.get("regionCityName"));
            sender.put("province", address.get("regionProvinceName"));
            sender.put("address", address.get("address"));
            sender.put("mobile", address.get("telephone"));
            sender.put("district", address.get("regionCountyName"));
            sender.put("name", "裕客网");  // todo 写死，根据实际情况可修改
            //接受者(必填部分)
            Map<String, Object> recipient = new HashMap<String, Object>();
            recipient.put("city", region_county_id.get("regionCityName").toString());
            recipient.put("province", region_county_id.get("regionProvinceName"));
            recipient.put("address", jsonObject.get("address"));
            recipient.put("district", region_county_id.get("regionCountyName"));
            recipient.put("mobile", jsonObject.get("mobile"));
            recipient.put("tel", jsonObject.get("telephone"));
            recipient.put("name", jsonObject.get("consignee"));
            //商品(必填部分)
            Map<String, Object> commodities;
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < objects1.size(); i++) {
                commodities = new HashMap();
                Object specName = objects1.getJSONObject(i).get("specName");  // todo 可增加重量和备注，备注不是必选项，暂不加
//                Object weight = objects1.getJSONObject(i).get("goodsWeight");
                commodities.put("name", specName.toString());
//                commodities.put("weight", weight.toString());  // 非必填项
                list.add(commodities);
            }
            data.put("sender", sender);
            data.put("recipient", recipient);
            data.put("commodities", list);
            data.put("customer_name", loginName);//
            data.put("customer_password", loginPassword);
            data.put("order_id", jsonObject.get("orderId"));//todo 替换订单id
            data.put("shipper_type", transid);//todo 某个快递公司id
            //data.put("month_no", "7551234567");
            data.put("pay_type", 1);  // 支付方式 ：1-寄方支付，2-收方支付, 3-月结  // 月结需要填月结卡号
            data.put("site_flag", siteFlag);  // 申通必填，其他可选
            bodys.put("data", JSON.toJSONString(data));
            try {
                HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
                System.out.println("进入这里吗");
                String s = EntityUtils.toString(response.getEntity());
                System.out.println(s);
                //获取response的body
                JSONObject jsonObject0 = JSONObject.parseObject(s);
                if ("0".equals(jsonObject0.get("code").toString())) {
                    JSONObject jsonObject1 = JSONObject.parseObject(jsonObject0.get("data").toString());
                    JSONObject jsonObject2 = JSONObject.parseObject(jsonObject1.get("result").toString());
                    waybill_no = jsonObject2.get("waybill_no").toString();//就是获取的快递单号
                    System.err.println("电子面单号码是" + waybill_no);
                    order_no = jsonObject2.get("order_no").toString();//商家自己的业务单号(订单号最好)

                    String pakgeName = jsonObject2.get("package_name").toString(); // 集包地名称
                    String originName = jsonObject2.get("origin_name").toString(); // 始发地名称
                    String originCode = jsonObject2.get("origin_code").toString(); // 始发地编号
                    String sortingCode = jsonObject2.get("sorting_code").toString(); // 分拣码
                    String destName = jsonObject2.get("dest_name").toString(); // 目的地名称
                    String routeCode = ""; // 二三段码
                    String sortation = destName; // 大字及一段码
                    if (PublicUtil.isNotEmpty(sortingCode)) {
                        String[] split = sortingCode.split("-");
                        if (PublicUtil.isNotEmpty(split[0])) {
                            sortation += split[0];
                        }

                        if (split.length >= 2 && PublicUtil.isNotEmpty(split[1])) {
                            routeCode = split[1];
                        }

                        if (split.length >= 3 && PublicUtil.isNotEmpty(split[2])) {
                            routeCode += " ";
                            routeCode += split[2];
                        }
                    }

                    String agentId = "";

                    // 获取该仓库下的打印机
                    if (warehouseId != null) {
                        Example example = new Example(WmsPrinter.class);
                        Example.Criteria criteria = example.createCriteria();
                        criteria.andEqualTo("warehouseId", warehouseId);
                        List<WmsPrinter> printers = wmsPrinterService.selectByExample(example);
                        if (printers != null && printers.size() > 0) {
                            agentId = printers.get(0).getAgentId();
                        }
                    }

                    if (PublicUtil.isEmpty(agentId)) {
                        System.out.println("打印失败-2");
                        return -2;
                    }

                    Boolean printit = printUtil.printit(sender, recipient, orderid, waybill_no, transid, list
                            , pakgeName, originName, originCode, routeCode, sortation, agentId);//todo 要传入参数，发送者接受者，路由集宝地,根据情况可修改
                    if (!printit) {
                        System.out.println("打印失败-3");
                        return -3;
                    }

                    notifyMsg = "您的订单" + orderid + "已经发货，由 " + expressName + " 配送，运单号：" + waybill_no + "，请注意查收";
                } else {
                    return -4;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return -4;
            }
        } else if (shippingType == 2) {  // 同城自配送
            expressId = 0L;  // 默认自配送为0
        } else {
            return -5;
        }

        //x修改订单配送表,同时订单状态
        Map map = new HashMap();
        map.put("orderId", order_no);
        if (expressId != null) {
            map.put("ExpressCompanyId", expressId.toString());
        }
        map.put("TrackingNumber", waybill_no);
        omcOrderFeignApi.saveorderDeliver(map);

        //保存物流单，修改订单状态为已经发货同时返回本订单的用户id，用来发送信鸽通知
        this.sendMsg(jsonObject,notifyMsg);
        return 1;

    }

    @Async
    @Override
    public  Integer updateWmsStoage(JSONArray json,Long warehouseId){
        for (int i = 0; i < json.size(); i++) {
            JSONObject objects1 = json.getJSONObject(i);
            WmsStorage wmsStorage = new WmsStorage();
            wmsStorage.setWarehouseId(warehouseId);
            wmsStorage.setSpecId(Long.valueOf(objects1.get("specId").toString()));
            List<WmsStorage> list = wmsStorageService.select(wmsStorage);
            for (WmsStorage item : list) {
                //todo 20191105 防止库存不足报错，如果库存数小于出库数，让库存数=出库数，
                if (item.getNumber() < Integer.valueOf(objects1.get("goodsNum").toString())) {
                    item.setNumber(Integer.valueOf(objects1.get("goodsNum").toString()));
                }
                //todo 如果库存减锁定库存小于0，让锁定库存=库存
                if (item.getNumber() - item.getLockNumber() < 0) {
                    item.setLockNumber(item.getNumber());
                }

                //todo 如果锁定库存小于出库数，让锁定库存=出库数
                if (item.getLockNumber() < Integer.valueOf(objects1.get("goodsNum").toString())) {
                    item.setLockNumber(Integer.valueOf(objects1.get("goodsNum").toString()));
                }
                //todo 如果存货《 出库数，存货数=num-lock_number-goodsNum，生产日期变更为最新
                //todo 否则,存货数=remainder-goodsNum
                if (item.getRemainder() <= Integer.valueOf(objects1.get("goodsNum").toString())) {
                    if (item.getNumber() - item.getLockNumber() - Integer.valueOf(objects1.get("goodsNum").toString()) > 0) {
                        item.setRemainder(item.getNumber() - item.getLockNumber() - Integer.valueOf(objects1.get("goodsNum").toString()));
                    } else {
                        item.setRemainder(0);
                    }

                    //取出生产日期,入库日期
                    Example exampleStockIn = new Example(WmsStockIn.class);
                    Example.Criteria criteriaStockIn = exampleStockIn.createCriteria();
                    exampleStockIn.setOrderByClause("mfg_date desc");
                    criteriaStockIn.andEqualTo("warehouseId", warehouseId);
                    criteriaStockIn.andEqualTo("specId", wmsStorage.getSpecId());
                    List<WmsStockIn> listWmsStockIn = wmsStockInService.selectByExample(exampleStockIn);
                    if (listWmsStockIn != null && listWmsStockIn.size() > 0) {
                        item.setMfgDate(listWmsStockIn.get(0).getMfgDate());
                        item.setStockinDate(listWmsStockIn.get(0).getInboundTime());
                    }

                } else {
                    item.setRemainder(item.getRemainder() - Integer.valueOf(objects1.get("goodsNum").toString()));
                }
                wmsStorageService.update(item);
            }//todo end
            //
            wmsStorageService.updateWarehouseStorage(warehouseId,
                    Long.valueOf(objects1.get("specId").toString()),
                    -Integer.valueOf(objects1.get("goodsNum").toString()),
                    -Integer.valueOf(objects1.get("goodsNum").toString()));
        }
        return 1;
    }

    @Async
    @Override
    public  Integer saveWmsStockOut(JSONArray json,Long warehouseId,Long orderId,Long userId){
        for (int i = 0; i < json.size(); i++) {
            JSONObject objects1 = json.getJSONObject(i);
            Long productId = Long.valueOf(objects1.get("productId").toString());

            WmsStockOut wmsStockOut = new WmsStockOut();
            wmsStockOut.setStockOutId(super.generateId());
            wmsStockOut.setWarehouseId(warehouseId);
            wmsStockOut.setOutType((byte) 0);
            wmsStockOut.setSpecId(Long.valueOf(objects1.get("specId").toString()));
            wmsStockOut.setProductId(productId);
            wmsStockOut.setOutNumber(Integer.valueOf(objects1.get("goodsNum").toString()));
            wmsStockOut.setOrderId(Long.valueOf(orderId));
            wmsStockOut.setUpdateId(userId);
            Date date = new Date();
            wmsStockOut.setOutboundTime(date);
            wmsStockOut.setUpdateTime(date);
            wmsStockOutService.save(wmsStockOut);
        }
        return 1;
    }

    @Async
    @Override
    public Integer updateWmsStorageRecorder(JSONArray json, Long warehouseId){
        for (int i = 0; i < json.size(); i++) {
            JSONObject objects1 = json.getJSONObject(i);
            WmsStorageRecord wmsStorageRecord = new WmsStorageRecord();
            if (Long.valueOf(objects1.get("unitSpec").toString()) > 0) {
                wmsStorageRecord.setSpecId(Long.valueOf(objects1.get("unitSpec").toString()));
            } else {
                wmsStorageRecord.setSpecId(Long.valueOf(objects1.get("specId").toString()));
            }
            wmsStorageRecord.setNumber(Integer.valueOf(objects1.get("goodsNum").toString()));
            wmsStorageRecord.setWarehouseId(warehouseId);
            wmsStorageRecordService.updateByWmsStorageRecord(wmsStorageRecord);
        }
        return 1;
    }

    @Async
    @Override
    public  Integer updateCmsSecKill(JSONArray json,String strUserId){
        for (int i = 0; i < json.size(); i++) {
            JSONObject objects1 = json.getJSONObject(i);
            List<CmsSecKillSkuDto> cmsSecKillSkuDtos = wmsStorageService.getSecKillSkus();
            for (CmsSecKillSkuDto cmsSecKillSkuDto : cmsSecKillSkuDtos) {
                if (cmsSecKillSkuDto.getSpecId().longValue() == Long.valueOf(objects1.get("specId").toString()).longValue()) {
                    cmsSecKillSkuDto.setStoreCount(-Integer.valueOf(objects1.get("goodsNum").toString()));
                    cmsSecKillSkuDto.setLockCount(-Integer.valueOf(objects1.get("goodsNum").toString()));
                    cmsSecKillSkuDto.setSaledCount(Integer.valueOf(objects1.get("goodsNum").toString()));

                    // add by wg 20190606 增加秒杀活动商品的处理 增加用户购买信息
                    int count = 0;
                    if (redisTemplate.hasKey(RedisKeyUtil.getSecKillSkuUserBuy(String.valueOf(cmsSecKillSkuDto.getSecKillId()), String.valueOf(cmsSecKillSkuDto.getSpecId()), strUserId))) {
                        count = (int) redisTemplate.opsForValue().get(RedisKeyUtil.getSecKillSkuUserBuy(String.valueOf(cmsSecKillSkuDto.getSecKillId()), String.valueOf(cmsSecKillSkuDto.getSpecId()), strUserId));
                    }

                    count += Integer.valueOf(objects1.get("goodsNum").toString());
                    redisTemplate.opsForValue().set(RedisKeyUtil.getSecKillSkuUserBuy(String.valueOf(cmsSecKillSkuDto.getSecKillId()), String.valueOf(cmsSecKillSkuDto.getSpecId()), strUserId), count);
                    // add by wg 20190606 增加秒杀活动商品的处理
                    cmcFeignApi.updateSecKillSkuCount(cmsSecKillSkuDto.getSecKillId(), cmsSecKillSkuDto.getSpecId(),
                            cmsSecKillSkuDto.getStoreCount(), cmsSecKillSkuDto.getLockCount(), cmsSecKillSkuDto.getSaledCount());

                }
            }
        }
        // add by wg 20190606 增加秒杀活动商品的处理
        //cmcFeignApi.updateSecKillSkusCount(cmsSecKillSkuDtos);
        return 1;
    }

    private Integer sendMsg(JSONObject jsonObject,String notifyMsg){

        if (PublicUtil.isEmpty(notifyMsg)) {
            notifyMsg = "您的订单" + jsonObject.get("orderId") + "已经发货";
        }

        String orderType = jsonObject.get("orderType").toString();
        Object userId1 = jsonObject.get("userId");

        MsgNotificationBody msg = new MsgNotificationBody();
        msg.setTitle("发货通知");
        msg.setContent(notifyMsg);
        msg.setTime(new Date());
        msg.setOrderType((byte) 1);
        msg.setMsgType("orderMsg");
        if(orderType.equals("1")){
            msg.setReceiveType((byte) 1);
        }else if(orderType.equals("2")){
            msg.setReceiveType((byte) 3);
        }

        opcSendNotifyFeignApi.sendnotify(userId1.toString(), "发货通知", notifyMsg, 0);
        opcSendNotifyFeignApi.sendnotify(userId1.toString(), "发货通知", JSON.toJSONString(msg), 1);

        return 1;
    }
}
